import 'dart:ffi';
import 'package:ffi/ffi.dart';

///对应C的结构体
final class MyStruct extends Struct {
  @Int32()
  external int a;

  @Float()
  external double b;

  external Pointer<Void> c;

  Pointer<Utf8> get uintPointer => c.cast<Utf8>();
  @override
  String toString() {
    return '$a,$b:${uintPointer.toDartString()}';
  }
}

///结构体
typedef TestCB = Void Function(Pointer<MyStruct>);

// 打开动态库
final dylib = DynamicLibrary.open(
    'G:\\yu-ui\\app-tools\\cpp-tools\\build\\Release\\cpp_tools.dll');

/// dart调用C函数测试用例
///
/// 传递结构体过去,将size大小以及字符串加到结构体上后返回
/// 后续还要测试赋值数据类型,队列,表,数组等
///
/// [test] : 指针结构体
///
/// [func] :  dart回调函数,由C调用
///
/// [size] :  基本类型
///
/// [test] :  常用的字符串转换
Pointer<MyStruct> dartToCTest(Pointer<MyStruct> test,
        Pointer<NativeFunction<TestCB>> func, int size, Pointer<Int8> str) =>
    _dartToCTest(test, func, size, str);

final _dartToCTest = dylib.lookupFunction<
    Pointer<MyStruct> Function(Pointer<MyStruct>,
        Pointer<NativeFunction<TestCB>>, Int32, Pointer<Int8>),
    Pointer<MyStruct> Function(Pointer<MyStruct>,
        Pointer<NativeFunction<TestCB>>, int, Pointer<Int8>)>('DartToCTest');

final Pointer<Pointer<Int8>> str = dylib.lookup<Pointer<Int8>>('version');

void cb(Pointer<MyStruct> c) {
  print(c.ref.c);
  c.ref.a += 10;
}

void main() {
  print(str.value);
  Pointer<Utf8> tmp1 = str.value.cast<Utf8>();
  print(tmp1.toDartString());

  Pointer<MyStruct> test = calloc.allocate<MyStruct>(sizeOf<MyStruct>());

  test.ref.a = 10;
  test.ref.b = 12.0;

  String testStr = "123344";
  Pointer<Int8> nativeValue = testStr.toNativeUtf8().cast<Int8>();

  Pointer<MyStruct> tmp =
      dartToCTest(test, Pointer.fromFunction<TestCB>(cb), 2, nativeValue);

  print(tmp.ref);
}
